#include <iostream>
#include <vector>

using namespace std;

#include <iostream>
#include <memory>

class A
{
public:
    A()
    {
        std::cout << "A constructor" << std::endl;
    }

    ~A()
    {
        std::cout << "~A destructor" << std::endl;
    }
};

//
//std::shared_ptr 有几个常用函数如下：
//
//void swap (unique_ptr& x)
//将 shared_ptr 对象的内容与对象 x 进行交换，在它们两者之间转移管理指针的所有权而不破坏或改变二者的引用计数。
//
//void reset()
//void reset (ponit p)
//没有参数时，先将管理的计数器引用计数减一并将管理的指针和计数器置清零。有参数 p 时，先做面前没有参数的操作，再管理 p 的所有权和设置计数器。
//
//element_type* get()
//得到其管理的指针。
//
//long int use_count()
//返回与当前智能指针对象在同一指针上共享所有权的 shared_ptr 对象的数量，如果这是一个空的 shared_ptr，则该函数返回 0。如果要用来检查 use_count 是否为 1，可以改用成员函数 unique 会更快。
//
//bool unique()
//返回当前 shared_ptr 对象是否不和其他智能指针对象共享指针的所有权，如果这是一个空的 shared_ptr，则该函数返回 false。
//
//element_type& operator\*()
//重载指针的 * 运算符，返回管理的指针指向的地址的引用。
//
//element_type* operator->()
//重载指针的 -> 运算符，返回管理的指针，可以访问其成员。
//explicit operator bool()
int display()
{
    {
        //初始化方式1
        std::shared_ptr<A> sp1(new A());

        std::cout << "use count: " << sp1.use_count() << std::endl;

        //初始化方式2
        std::shared_ptr<A> sp2(sp1);
        std::cout << "use count: " << sp1.use_count() << std::endl;

        //主动释放SP2的所有引用计数！
        sp2.reset();
        std::cout << "use count: " << sp1.use_count() << std::endl;

        {
            std::shared_ptr<A> sp3 = sp1;
            std::cout << "use count: " << sp1.use_count() << std::endl;
        }

        std::cout << "use count: " << sp1.use_count() << std::endl;
    }

    return 0;
}


/**
 * 裸指针初始化多个share_ptr
 */
void display2()
{
    string s = "p";
    shared_ptr<string> p = make_shared<string>(s);
    /*不要这样做*/
    shared_ptr<string> p1 = make_shared<string>(s);
    cout<<*p<<endl;
    cout<<*p1<<endl;

    auto *p0 = new std::string("hello");
    std::shared_ptr<std::string> p2(p0);
    /*不要这样做*/
    std::shared_ptr<std::string> p3(p0);
    cout<<*p2<<endl;
    cout<<*p3<<endl;
}


int main()
{
    //初始化方式1
//    std::shared_ptr<int> sp1(new int(123));
//
//    //初始化方式2
//    std::shared_ptr<int> sp2;
//    sp2.reset(new int(123));
//
//    //初始化方式3
//    std::shared_ptr<int> sp3 = std::make_shared<int>(123);   //make_shared 去初始化;



//    display();
    display2();


    return 0;
}


